package org.dfyy.postgisdemo.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.dfyy.postgisdemo.mapper.RadarMapper;
import org.dfyy.postgisdemo.pojo.Radar;
import org.dfyy.postgisdemo.pojo.dto.GeometryDto;
import org.dfyy.postgisdemo.pojo.dto.GeometryVo;
import org.dfyy.postgisdemo.service.RadarService;
import org.dfyy.postgisdemo.uitls.MyArrayUtil;
import org.springframework.stereotype.Service;


import java.awt.*;
import java.awt.geom.Point2D;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author 书山
 * @description 针对表【tb_radar(雷达对象表)】的数据库操作Service实现
 * @createDate 2024-04-12 13:55:44
 */
@Service
@RequiredArgsConstructor
public class RadarServiceImpl extends ServiceImpl<RadarMapper, Radar>
        implements RadarService {

    private final RadarMapper radarMapper;


    /*
        INSERT
     */

    // 新增点
    @Override
    public boolean savePoint(Radar radar) {
        try {
            if (ObjectUtil.isNotEmpty(radar)) {
                // 假数据
                radar.setMc("sb_" + (int) (Math.random() * 100));
                radar.setXh("xh_" + (int) (Math.random() * 100));
                radar.setBz("No remarks");
                return radarMapper.insertPoint(radar);
            }

        } catch (Exception e) {
            System.err.println("点新增失败\n");
            e.printStackTrace();
        }

        return false;
    }

    // 新增线
    @Override
    public boolean saveLine(GeometryDto geometryDto) {
        try {
            if (geometryDto == null || CollUtil.isEmpty(geometryDto.getCoordinates())) {
                System.out.println("新增线 - 参数不正确");
                return false;
            }


            String xys = listConversionString(geometryDto.getCoordinates());
            return radarMapper.insertLineString(geometryDto.getMc(), xys);
        } catch (Exception e) {
            System.out.println("新增线失败");
            e.printStackTrace();
        }
        return false;
    }


    // 新增面
    @Override
    public boolean savePolygon(GeometryDto geometryDto) {
        try {
            if (geometryDto == null || CollUtil.isEmpty(geometryDto.getCoordinates())) {
                System.out.println("新增面 - 参数不正确");
                return false;
            }

            String xys = listConversionString(geometryDto.getCoordinates());
            return radarMapper.insertPolygon(geometryDto.getMc(), xys);
        } catch (Exception e) {
            System.out.println("新增面失败");
            e.printStackTrace();
        }
        return false;
    }


    /*
        DELETE
     */
    // 批量删除 [点/线/面]
    @Override
    public boolean batchDeleteByIds(List<Integer> ids) {
        try {
            // 判断集合是否为null 或者为new ArrayList<>()
            if (CollUtil.isEmpty(ids)) {
                System.out.println("请提供正确数据");
                return false;
            }
            radarMapper.batchDeleteByIds(ids);
            return true;
        } catch (Exception e) {
            System.out.println("批量删除失败");
            e.printStackTrace();
        }
        return false;
    }



    /*
        UPDATE
     */
    // 修改点
    @Override
    public boolean updatePoint(Radar radar) {
        try{

            if (ObjectUtil.isEmpty(radar)){
                System.out.println("修改点方法的参数不合法");
                return false;
            }

            if (radarMapper.updatePoint(radar)){
                return true;
            }
        }catch (Exception e){
            System.out.println("修改点失败");
            e.printStackTrace();
        }
        return false;
    }

    // 修改线
    @Override
    public boolean updateLineString(GeometryDto dto) {
        try{

            if (ObjectUtil.isEmpty(dto)){
                System.out.println("修改线方法的参数不合法");
                return false;
            }

            if (radarMapper.updateLineString(dto)){
                return true;
            }
        }catch (Exception e){
            System.out.println("修改线失败");
            e.printStackTrace();
        }
        return false;
    }

    // 修改面
    @Override
    public boolean updatePolygon(GeometryDto dto) {
        try{

            if (ObjectUtil.isEmpty(dto)){
                System.out.println("修改面方法的参数不合法");
                return false;
            }

            if (radarMapper.updatePolygon(dto)){
                return true;
            }
        }catch (Exception e){
            System.out.println("修改面失败");
            e.printStackTrace();
        }
        return false;
    }





    /*
        SELECT
     */



    // 根据点 查询出点
    @Override
    public Radar queryPointByPoint(Radar radar) {
        return radarMapper.selectPoint(radar);
    }

    // 根据所给的图形 查询出被这个图形包含的点/线/面
    @Override
    public HashMap<String, List<Radar>> searchPoint(List<Object> list) {

        try {
            // 调用方法 将list集合变为 字符串
            String str = MyArrayUtil.removeOddCommas(list);

            List<Radar> points = radarMapper.selectListRadar(str);  // 点坐标集合
            List<Radar> lineStrings = radarMapper.selectLineString(str);  // 线坐标集合
            List<Radar> polygons = radarMapper.selectPolygon(str);        // 面坐标集合

            // 修改里面的内容
            // 线
            lineStrings = lineStrings.stream()
                    .map(radar -> {
                        String originalLineStrings = radar.getTemp();
                        List<List<String>> extractedContent = extractInnermostBracketContentAsLists(originalLineStrings);
                        radar.setLineStrings(extractedContent);
                        return radar;
                    })
                    .collect(Collectors.toList());
            // 面
            polygons = polygons.stream()
                    .map(radar -> {
                        String originalPolygons = radar.getTemp();
                        List<List<String>> extractedContent = extractInnermostBracketContentAsLists(originalPolygons);
                        radar.setPolygons(extractedContent);
                        return radar;
                    })
                    .collect(Collectors.toList());

            HashMap<String, List<Radar>> result = new HashMap<>();
            result.put("points", points);
            result.put("lineStrings", lineStrings);
            result.put("polygons", polygons);

            System.out.println("POINT:\n");
            System.out.println(points + "\n");
            System.out.println("LINESTRING:\n");
            System.out.println(lineStrings + "\n");
            System.out.println("POLYGON:\n");
            System.out.println(polygons + "\n");

            return result;
        } catch (Exception e) {
            System.err.println("查询失败");
            e.printStackTrace();
        }
        return null;
    }

    // 查询所有的点
    @Override
    public List<Radar> queryAllPoint() {
        try{
            return radarMapper.selectAllPoint();
        }catch (Exception e){
            System.out.println("查询所有的点失败");
            e.printStackTrace();
        }

        return null;
    }

    // 查询所有的线
    @Override
    public List<GeometryVo> queryAllLineString() {
       try{
           List<GeometryVo> lineStrings = radarMapper.queryAllLineString();
           lineStrings = lineStrings.stream()
                   .map(vo -> {
                       String originalLineStrings = vo.getTemp();
                       List<List<String>> extractedContent = extractInnermostBracketContentAsLists(originalLineStrings);
                       vo.setGeometry(extractedContent);
                       return vo;
                   })
                   .collect(Collectors.toList());
           return lineStrings;
       }catch (Exception e){
           System.out.println("查询所有的线失败");
           e.printStackTrace();
       }
       return null;
    }

    // 查询所有的面
    @Override
    public List<GeometryVo> queryAllPolygon() {
       try {
           List<GeometryVo> polygons = radarMapper.queryAllPolygon();
           polygons = polygons.stream()
                   .map(vo -> {
                       String originalLineStrings = vo.getTemp();
                       List<List<String>> extractedContent = extractInnermostBracketContentAsLists(originalLineStrings);
                       vo.setGeometry(extractedContent);
                       return vo;
                   })
                   .collect(Collectors.toList());
           return polygons;
       }catch (Exception e){
           System.out.println("查询所有的面失败");
           e.printStackTrace();
       }
       return null;
    }




    /*
        UTILS METHOD
     */
    /**
     * 将 "LINESTRING(x y, x y, x y)" 格式的内容 --> 变为 [ [x,y], [x,y], [x,y]] 去掉英文和括号同时 变为一个二维数据
     *
     * @param input 要处理的字符串
     * @return 转换好的字符串
     */
    public static List<List<String>> extractInnermostBracketContentAsLists(String input) {
        // 正则表达式匹配最内层括号内的内容
        String regex = "\\(([^()]*)\\)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(input);

        if (matcher.find()) {
            // 获取最内层括号内的内容并分割成字符串数组
            String content = matcher.group(1).trim();
            String[] pairs = content.split(",\\s*"); // 使用逗号和可能存在的空格进行分割

            // 将字符串数组转换为字符串列表的列表
            List<List<String>> result = new ArrayList<>();
            for (String pair : pairs) {
                String[] numbers = pair.trim().split("\\s+");
                if (numbers.length == 2) {
                    result.add(Arrays.asList(numbers[0], numbers[1]));
                }
            }

            return result;
        }

        // 如果没有找到最内层括号，返回空集合列表
        return new ArrayList<>();
    }


    /**
     * 通过指定集合 返回指定格式字符串
     * @param list
     * @return
     */
    private String listConversionString(List<String> list) {
        // 操作字符串对象
        StringBuffer xys = new StringBuffer();

        // 遍历集合
        for (int i = 0; i < list.size(); i += 2) {
            if (i > 0) {
                xys.append(", ");
            }

            xys.append(list.get(i));

            if (i + 1 < list.size()) {
                xys.append(" ").append(list.get(i + 1));
            }
        }
        return xys.toString();
    }

}




